package com.markerhub.aspect;

import com.markerhub.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author by MaXiaofeng
 * @Description 用户超时取餐时间校验AOP
 * @Date 2022/2/21 12:36
 * @Version 1.0.0
 */

/**
 * @Description 其中：
 * * @Aspect 表明是一个切面类
 * * @Component 将当前类注入到Spring容器内
 * * @Pointcut 切入点，其中execution用于使用切面的连接点。使用方法：execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选)) ，可以使用通配符匹配字符，*可以匹配任意字符。
 * * @Before 在方法前执行
 * * @After 在方法后执行
 * * @AfterReturning 在方法执行后返回一个结果后执行
 * * @AfterThrowing 在方法执行过程中抛出异常的时候执行
 * * @Around 环绕通知，就是可以在执行前后都使用，这个方法参数必须为ProceedingJoinPoint，proceed()方法就是被切面的方法，上面四个方法可以使用JoinPoint，JoinPoint包含了类名，被切面的方法名，参数等信息。
 * @Author
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2019-09-25
 */
@Slf4j
@Aspect
@Component
public class TimeOutHandler {
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 定义Pointcut,Pointcut的名称是timeOutAspect，
     * 此方法不能有返回值和参数，该方法只是一个标识
     */
    @Pointcut("execution(public * com.markerhub.controller.OrderController.*(..))")
    private void timeOutAspect() {
    }

    /**
     * 在OrderController的任何方法执行前检查外卖订单的时间有效性
     *
     * @param joinPoint
     */
    @Before("timeOutAspect()")
    private void checkTimeValidity(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        log.info("注解方式AOP开始拦截, 当前拦截的方法名: " + method.getName());
        int updateOrderNum = orderMapper.updateTimeValidity();
        log.info("更新" + updateOrderNum + "条过期外卖订单数据,用户取餐超时");
    }

}
